/**
 * 
 */
package com.google.code.jkippt.http.paging;

import java.util.Iterator;

import com.google.code.jkippt.http.APIClient;
import com.google.code.jkippt.http.CommunicationException;
import com.google.code.jkippt.http.EndPointFactory;
import com.google.code.jkippt.http.ServerErrorException;
import com.google.code.jkippt.parser.PageParser;
import com.google.code.jkippt.parser.PageParserBuilder;
import com.google.code.jkippt.parser.ParserException;

/**
 * Iterator over result pages.
 * @author Federico De Faveri defaveri@gmail.com
 */
public class PageIterator<T> implements Iterator<Page<T>> {

	protected APIClient client;
	protected String nextPageEndPoint;
	protected PageParserBuilder<T> parserBuilder;

	/**
	 * @param client
	 * @param parser
	 * @param currentPage
	 * @param type
	 */
	public PageIterator(APIClient client, PageParserBuilder<T> parserBuilder, String firstPageEndPoint) {
		this.client = client;
		this.parserBuilder = parserBuilder;
		this.nextPageEndPoint = firstPageEndPoint;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean hasNext() {
		return nextPageEndPoint!=null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Page<T> next() {
		if (!hasNext()) throw new IllegalStateException("There are no more pages");
		return getNextPage();
	}

	protected Page<T> getNextPage()
	{
		try {
			Page<T> nextPage = getPage(nextPageEndPoint);
			Meta meta = nextPage.getMeta();
			String nextEndPoint = meta.getNext();
			nextPageEndPoint = (nextEndPoint!=null)?EndPointFactory.getInstance().getNextPageEndPoint(nextEndPoint):null;

			return nextPage;
		} catch (Exception e) {
			throw new RuntimeException("An error occurred getting the next page", e);
		}
	}

	protected Page<T> getPage(String endPoint) throws ServerErrorException, CommunicationException, ParserException
	{
		String json = client.get(endPoint);
		PageParser<T> parser = parserBuilder.getParser(json);
		return new Page<T>(parser);
	}


	/**
	 * {@inheritDoc}
	 */
	public void remove() {
		throw new UnsupportedOperationException();	
	}

}
